import React, { useEffect, useMemo, useState } from 'react'
import '../styles.css'
import { TerminalPage } from './TerminalPage'
import { ThemeToggle } from '../components/ThemeToggle'
import { Layout } from '../components/Layout'
import { ToastProvider, useToast } from '../components/Toast'
import { SkeletonRows } from '../components/Skeleton'
import { DataTable, Column } from '../components/DataTable'
import { LogsModal } from '../components/LogsModal'
import { StepForm } from '../components/StepForm'
import * as yup from 'yup'
import { EditServerModal } from '../components/EditServerModal'
import { LoadingState, EmptyState, ErrorState } from '../components/States'

type ServerRead = {
  id: number
  name: string
  host: string
  port: number
  username: string
  description?: string | null
}

type ServerCreate = {
  name: string
  host: string
  port: number
  username: string
  password: string
  description?: string
}

async function api<T>(input: RequestInfo, init?: RequestInit): Promise<T> {
  const resp = await fetch(input, {
    ...init,
    headers: {
      'Content-Type': 'application/json',
      ...(init?.headers || {}),
    },
  })
  if (!resp.ok) throw new Error(await resp.text())
  return resp.json()
}

function AppInner(): JSX.Element {
  const [servers, setServers] = useState<ServerRead[]>([])
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [selected, setSelected] = useState<ServerRead | null>(null)
  const toast = useToast()
  const [logServerId, setLogServerId] = useState<number | null>(null)
  const [editing, setEditing] = useState<ServerRead | null>(null)

  const [form, setForm] = useState<ServerCreate>({
    name: '',
    host: '',
    port: 22,
    username: '',
    password: '',
    description: '',
  })

  const load = async () => {
    setLoading(true)
    setError(null)
    try {
      const data = await api<ServerRead[]>('/api/servers/')
      setServers(data)
    } catch (e: any) {
      setError(e.message)
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    load()
  }, [])

  const onSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    try {
      await api<ServerRead>('/api/servers/', {
        method: 'POST',
        body: JSON.stringify(form),
      })
      setForm({ name: '', host: '', port: 22, username: '', password: '', description: '' })
      await load()
      toast.show('保存成功', 'success')
    } catch (e: any) {
      toast.show(e.message || '保存失败', 'error')
    }
  }

  if (selected) {
    return <TerminalPage server={selected} onBack={() => setSelected(null)} />
  }

  return (
    <Layout>
      <div className="container">
      <div className="panel">
        <div className="header">
          <h3 className="title">服务器列表</h3>
          <div className="toolbar">
            {loading && <span className="muted">加载中...</span>}
            {error && <span style={{ color: 'salmon' }}>{error}</span>}
            <div className="spacer" />
            <ThemeToggle />
            <button className="btn btn-sm" onClick={load}>刷新</button>
          </div>
        </div>
        <div className="content">
          {loading && <SkeletonRows rows={6} />}
          {!loading && error && (
            <ErrorState message={error} onRetry={load} />
          )}
          {!loading && !error && servers.length === 0 && (
            <EmptyState title="暂无服务器" description="请先添加一台服务器以开始会话" action={<button className="btn btn-primary btn-sm" onClick={() => window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' })}>去添加</button>} />
          )}
          {!loading && !error && servers.length > 0 && (
            <DataTable
              data={servers}
              searchableKeys={["name", "host", "username"]}
              columns={[
                { key: "name", title: "名称", sortable: true, render: (s) => <span className="badge badge-primary mono">{s.name}</span> },
                { key: "host", title: "地址", sortable: true, render: (s) => <span className="mono">{s.host}:{s.port}</span> },
                { key: "username", title: "用户名", sortable: true, render: (s) => <span className="mono">{s.username}</span> },
                { key: "description", title: "描述", render: (s) => s.description || '-' },
                { key: "id", title: "操作", render: (s) => (
                  <div style={{ display: 'flex', gap: 8 }}>
                    <button className="btn btn-primary btn-sm" onClick={() => setSelected(s)}>WebSSH</button>
                    <button className="btn btn-sm" onClick={() => setEditing(s)}>编辑</button>
                    <button className="btn btn-sm" onClick={() => setLogServerId(s.id)}>日志</button>
                  </div>
                )},
              ] as Column<ServerRead>[]}
            />
          )}
        </div>
      </div>

      <div style={{ height: 14 }} />

      <div className="panel">
        <div className="header">
          <h3 className="title">添加服务器</h3>
        </div>
        <div className="content">
          <StepForm
            initial={form}
            steps={[
              {
                title: '基础信息',
                fields: [
                  { key: 'name', label: '名称', placeholder: '例如：生产机-1', required: true },
                  { key: 'description', label: '描述（可选）', placeholder: '备注信息' },
                ],
                schema: yup.object({
                  name: yup.string().required('请填写名称'),
                  description: yup.string().optional(),
                }),
              },
              {
                title: '连接配置',
                fields: [
                  { key: 'host', label: '主机/IP', placeholder: '192.168.1.2 或 example.com', required: true },
                  { key: 'port', label: '端口', type: 'number', placeholder: '默认 22' },
                  { key: 'username', label: '用户名', required: true },
                  { key: 'password', label: '密码', type: 'password' },
                ],
                schema: yup.object({
                  host: yup.string().required('请填写主机/IP'),
                  port: yup.number().min(1).max(65535).optional(),
                  username: yup.string().required('请填写用户名'),
                  password: yup.string().optional(),
                }),
              },
            ]}
            onSubmit={async (val) => {
              await api<ServerRead>('/api/servers/', { method: 'POST', body: JSON.stringify(val) })
              setForm({ name: '', host: '', port: 22, username: '', password: '', description: '' })
              await load()
              toast.show('保存成功', 'success')
            }}
          />
        </div>
      </div>
      {logServerId && <LogsModal serverId={logServerId} onClose={() => setLogServerId(null)} />}
      {editing && <EditServerModal server={editing} onClose={() => setEditing(null)} onSaved={load} />}
      </div>
    </Layout>
  )
}

export function App(): JSX.Element {
  return (
    <ToastProvider>
      <AppInner />
    </ToastProvider>
  )
}

